package com.example.smartwaterapi.controller;

import com.example.smartwaterapi.common.api.RestApiResponse;
import com.example.smartwaterapi.service.WechatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;

/**
 * 微信公众号网页授权控制器
 * 处理从公众号菜单到小程序的授权跳转流程
 */
@Slf4j
@Controller
@RequestMapping("/wechat/auth")
public class WechatAuthController {

    @Autowired
    private WechatService wechatService;

    @Autowired
    private WxMpService wxMpService;

    @Value("${wechat.official.appid:}")
    private String officialAccountAppId;

    @Value("${app.domain:https://xhd.szxhdkj.com}")
    private String appDomain;

    @Value("${wechat.miniprogram.appid:}")
    private String miniprogramAppId;

    /**
     * 生成微信网页授权URL
     * 公众号菜单应该链接到这个接口
     */
    @GetMapping("/authorize")
    public RedirectView authorize(
            @RequestParam(required = false) String state,
            @RequestParam(required = false) String redirectUri,
            HttpServletRequest request) {
        
        try {
            log.info("🚀 开始微信网页授权流程");
            
            // 构建回调URL
            String callbackUrl = appDomain + "/wechat/auth/callback";
            String encodedCallbackUrl = URLEncoder.encode(callbackUrl, "UTF-8");
            
            // 构建state参数（用于回调时识别来源）
            String authState = StringUtils.hasText(state) ? state : "miniprogram_auth";
            if (StringUtils.hasText(redirectUri)) {
                authState += "|" + redirectUri;
            }
            
            // 构建微信网页授权URL
            // 参考：https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
            String authUrl = String.format(
                "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=%s&" +
                "redirect_uri=%s&" +
                "response_type=code&" +
                "scope=snsapi_userinfo&" +
                "state=%s#wechat_redirect",
                officialAccountAppId,
                encodedCallbackUrl,
                authState
            );
            
            log.info("📍 重定向到微信授权页面: {}", authUrl);
            return new RedirectView(authUrl);
            
        } catch (UnsupportedEncodingException e) {
            log.error("❌ URL编码失败", e);
            return new RedirectView("/error?msg=auth_failed");
        }
    }

    /**
     * 微信网页授权回调处理
     * 获取授权码后跳转到小程序
     */
    @GetMapping("/callback")
    public void callback(@RequestParam String code, 
            @RequestParam(required = false) String state,
                        HttpServletResponse response) throws Exception {
        log.info("🎯 收到微信授权回调 - code={}, state={}", code, state);
        
        try {
            // 1. 通过授权码获取用户信息
            WechatService.WechatOfficialUserInfo userInfo = wechatService.getOfficialAccountUserInfo(code);
            String openid = userInfo.getOpenid();
            String nickname = userInfo.getNickname();
            
            log.info("✅ 获取到公众号用户信息 - openid={}, nickname={}", openid, nickname);
            
            // 2. 返回HTML页面，用于web-view跳转回小程序
            response.setContentType("text/html; charset=UTF-8");
            String html = buildMiniprogramRedirectHtml(openid, state);
            response.getWriter().write(html);
            
        } catch (Exception e) {
            log.error("❌ 处理微信授权回调失败", e);
            response.setContentType("text/html; charset=UTF-8");
            response.getWriter().write(buildErrorHtml("授权失败，请重试"));
        }
    }
    

    /**
     * 构建错误页面
     */
    private String buildErrorHtml(String errorMessage) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>授权失败</title>
            </head>
            <body>
                <div style="text-align: center; padding: 50px; font-family: Arial, sans-serif;">
                    <h2>❌ %s</h2>
                    <p>请返回小程序重试</p>
                    <button onclick="history.back()" style="padding: 10px 20px; background: #007aff; color: white; border: none; border-radius: 5px;">返回</button>
                </div>
            </body>
            </html>
            """.formatted(errorMessage);
    }

    /**
     * 构建返回给 web-view 的 HTML 页面
     * 统一使用 web-view + JS 跳转方案
     */
    private String buildMiniprogramRedirectHtml(String officialAccountOpenid, String state) {
        // 🎯 构建绝对路径，确保跳转正确
        String path = "/pages/login/login?officialAccountOpenid=" + officialAccountOpenid + "&fromOfficialAccount=true&fromWebViewAuth=true";
            
            // 如果有额外的状态参数，添加到路径中
            if (StringUtils.hasText(state) && state.contains("|")) {
                String[] parts = state.split("\\|", 2);
                if (parts.length > 1) {
                try {
                    path += "&redirect=" + URLEncoder.encode(parts[1], "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    log.warn("编码redirect参数失败: {}", parts[1]);
                }
            }
        }
        
        log.info("🚀 构建小程序跳转路径: {}", path);
        
        // 返回包含跳转逻辑的 HTML 页面
        return String.format("""
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="utf-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>授权成功</title>
                <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
                <style>
                    body {
                        font-family: -apple-system, BlinkMacSystemFont, sans-serif;
                        text-align: center;
                        padding: 60px 20px;
                        background: linear-gradient(135deg, #667eea 0%%, #764ba2 100%%);
                        color: white;
                        margin: 0;
                        min-height: 100vh;
                        display: flex;
                        flex-direction: column;
                        justify-content: center;
                    }
                    .container {
                        max-width: 400px;
                        margin: 0 auto;
                    }
                    .success-icon {
                        font-size: 64px;
                        margin-bottom: 20px;
                    }
                    .title {
                        font-size: 24px;
                        margin-bottom: 16px;
                        font-weight: 600;
                    }
                    .subtitle {
                        font-size: 16px;
                        opacity: 0.9;
                        margin-bottom: 30px;
                    }
                    .loading {
                        display: inline-block;
                        width: 20px;
                        height: 20px;
                        border: 2px solid rgba(255,255,255,0.3);
                        border-radius: 50%%;
                        border-top-color: white;
                        animation: spin 1s ease-in-out infinite;
                        margin-right: 8px;
                    }
                    @keyframes spin {
                        to { transform: rotate(360deg); }
                    }
                    .retry-btn {
                        background: rgba(255,255,255,0.2);
                        border: 1px solid rgba(255,255,255,0.3);
                        color: white;
                        padding: 12px 24px;
                        border-radius: 6px;
                        cursor: pointer;
                        margin-top: 20px;
                        font-size: 16px;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <div class="success-icon">✅</div>
                    <div class="title">授权成功</div>
                    <div class="subtitle">
                        <span class="loading"></span>
                        正在跳转回小程序...
                    </div>
                    <button class="retry-btn" onclick="sendPostMessageAgain()" style="display: none;" id="retryBtn">重试跳转</button>
                </div>
                
                <script>
                    const openid = '%s';
                    const path = '%s';
                    let retryCount = 0;
                    const maxRetries = 5;
                    let messagesSent = 0;
                    
                    // 主函数：发送消息到小程序
                    function sendPostMessage() {
                        if (typeof wx !== 'undefined' && wx.miniProgram && wx.miniProgram.postMessage) {
                            console.log('🚀 发送postMessage到小程序, openid:', openid);
                            
                            // 构建消息数据
                            const messageData = {
                                type: 'officialAccountAuth',
                                openid: openid,
                                officialAccountOpenid: openid,
                                fromOfficialAccount: true,
                                timestamp: Date.now()
                            };
                            
                            // 发送消息
                            wx.miniProgram.postMessage({ data: messageData });
                            messagesSent++;
                            
                            // 设置定时器，多次发送确保接收
                            schedulePostMessages();
                            
                            // 同时尝试直接跳转
                            tryDirectNavigation();
                        } else {
                            console.error('❌ wx.miniProgram.postMessage 不可用');
                            showRetryButton();
                        }
                    }
                    
                    // 尝试直接跳转 - 作为备用方案
                    function tryDirectNavigation() {
                        setTimeout(() => {
                            if (typeof wx !== 'undefined' && wx.miniProgram) {
                                // 尝试多种跳转方式
                                if (wx.miniProgram.redirectTo) {
                                    console.log('🔄 尝试使用 redirectTo 跳转');
                                    wx.miniProgram.redirectTo({ url: path });
                                } else if (wx.miniProgram.navigateTo) {
                                    console.log('🔄 尝试使用 navigateTo 跳转');
                                    wx.miniProgram.navigateTo({ url: path });
                                } else if (wx.miniProgram.switchTab) {
                                    console.log('🔄 尝试使用 switchTab 跳转到首页');
                                    wx.miniProgram.switchTab({ url: '/pages/index/index' });
                                }
                            }
                        }, 1500);
                    }
                    
                    // 安排多次发送消息
                    function schedulePostMessages() {
                        // 延迟发送确保接收
                        for (let i = 1; i <= 5; i++) {
                            setTimeout(() => {
                                if (typeof wx !== 'undefined' && wx.miniProgram && wx.miniProgram.postMessage) {
                                    const messageData = {
                                        type: 'officialAccountAuth',
                                        openid: openid,
                                        officialAccountOpenid: openid,
                                        fromOfficialAccount: true,
                                        timestamp: Date.now(),
                                        messageCount: messagesSent + i
                                    };
                                    wx.miniProgram.postMessage({ data: messageData });
                                    console.log(`🔄 第${i}次发送postMessage确保接收`);
                                }
                            }, i * 300); // 缩短间隔，更快发送消息
                        }
                        
                        // 5秒后如果还在页面，显示重试按钮
                        setTimeout(() => {
                            showRetryButton();
                        }, 5000); // 缩短等待时间
                    }
                    
                    // 显示重试按钮
                    function showRetryButton() {
                        const retryBtn = document.getElementById('retryBtn');
                        if (retryBtn) {
                            retryBtn.style.display = 'inline-block';
                        }
                    }
                    
                    // 重新发送消息
                    function sendPostMessageAgain() {
                        retryCount++;
                        if (retryCount <= maxRetries) {
                            sendPostMessage();
                            document.querySelector('.subtitle').innerHTML = 
                                '<span class="loading"></span>正在重新尝试跳转 (' + retryCount + '/' + maxRetries + ')...';
                        } else {
                            document.querySelector('.subtitle').innerHTML = '跳转失败，请返回小程序重试';
                        }
                    }
                    
                    // 页面加载完成后自动发送消息
                    window.onload = function() {
                        // 立即发送第一条消息
                        sendPostMessage();
                    };
                </script>
            </body>
            </html>
        """, officialAccountOpenid, path);
    }

    /**
     * 获取授权链接（给小程序调用）
     */
    @GetMapping("/url")
    @ResponseBody
    public RestApiResponse<String> getAuthUrl(
            @RequestParam(required = false) String state,
            @RequestParam(required = false) String redirectUri) {
        
        try {
            String authUrl = appDomain + "/wechat/auth/authorize";
            if (StringUtils.hasText(state)) {
                authUrl += "?state=" + URLEncoder.encode(state, "UTF-8");
            }
            if (StringUtils.hasText(redirectUri)) {
                String separator = authUrl.contains("?") ? "&" : "?";
                authUrl += separator + "redirectUri=" + URLEncoder.encode(redirectUri, "UTF-8");
            }
            
            return RestApiResponse.ok(authUrl);
            
        } catch (UnsupportedEncodingException e) {
            log.error("❌ 生成授权链接失败", e);
            return RestApiResponse.businessError("50006", "生成授权链接失败");
        }
    }

    /**
     * 为小程序提供获取公众号openid的接口
     * 支持你提到的操作逻辑：pages/index/index?openid=@https://xhd.szxhdkj.com/wechat/auth/authorize?state=miniprogram_auth
     */
    @GetMapping("/get-openid")
    @ResponseBody
    public RestApiResponse<?> getOpenidForMiniprogram(@RequestParam String code) {
        try {
            log.info("🔍 小程序请求获取公众号openid - code={}", code);
            
            // 通过授权码获取用户信息
            var authResult = wechatService.getOfficialAccountUserInfo(code);
            if (authResult == null || !StringUtils.hasText(authResult.getOpenid())) {
                log.error("❌ 获取用户信息失败");
                return RestApiResponse.businessError("50007", "获取用户信息失败");
            }
            
            // 返回用户信息给小程序
            var result = new java.util.HashMap<String, Object>();
            result.put("openid", authResult.getOpenid());
            result.put("nickname", authResult.getNickname());
            result.put("avatar", authResult.getHeadimgurl());
            
            log.info("✅ 成功返回公众号openid给小程序 - openid={}", authResult.getOpenid());
            
            return RestApiResponse.ok(result);
            
        } catch (Exception e) {
            log.error("❌ 获取公众号openid失败", e);
            return RestApiResponse.businessError("50008", "系统错误");
        }
    }

    /**
     * 错误页面
     */
    @GetMapping("/error")
    @ResponseBody
    public String error(@RequestParam(required = false) String msg) {
        String message = "Unknown error";
        if (StringUtils.hasText(msg)) {
            switch (msg) {
                case "auth_failed":
                    message = "Authorization failed";
                    break;
                case "process_failed":
                    message = "Process failed";
                    break;
                default:
                    message = msg;
            }
        }
        
        return String.format(
            "<html><body>" +
            "<h3>Authorization Failed</h3>" +
            "<p>%s</p>" +
            "<p>Please try again or contact customer service</p>" +
            "</body></html>",
            message
        );
    }
} 